package edu.berkeley.guir.webquilt;


/**
 * An expandable array of bytes.
 *
 * <P>
 * This software is distributed under the
 * <A HREF="http://guir.cs.berkeley.edu/projects/COPYRIGHT.txt">
 * Berkeley Software License</A>.
 *
 * <PRE>
 * Revisions:  - WebQuilt-v1.0-2.0.0, May 15 2000, jheer
 *               Created class
 * </PRE>
 *
 * @author  Jeffrey Heer (
 *          <A HREF="mailto:jheer@hkn.eecs.berkeley.edu">jheer@hkn.eecs.berkeley.edu</A>
 *          )
 * @since   JDK 1.3
 * @version WebQuilt-v1.0-2.0.0, Mar 10 2001
 */
public class ByteVector {

    public static final int DEFAULT_SIZE = 256;

    private byte[] bytes;
    private int    size;

    /**
     * ByteVector constructor. Initializes a byte vector
     *  with a default capacity specified by 
     *  ByteVector.DEFAULT_SIZE.
     */
    public ByteVector() {
	bytes = new byte[DEFAULT_SIZE];
	size = 0;
    } //


    /**
     * ByteVector constructor. Initializes a byte vector
     *  with the specified initial capacity.
     * @param capacity initial capacity
     */
    public ByteVector(int capacity) {
	bytes = new byte[capacity];
	size = 0;
    } //


    /**
     * Get the byte at the specified index.
     * @param i the index into the vector
     * @return the byte value at index i
     */
    public byte get(int i) {
	return bytes[i];
    } //


    /**
     * Set the byte value at the specified index.
     * @param i the index to set
     * @param b the byte value to set
     */
    public void set(int i, byte b) {
	resize(i);

	bytes[i] = b;

	if ( i > size ) {
	    size = i;
	}
    } //


    /**
     * Append bytes to the end of the vector.
     * @param buf a buffer containing the bytes to append
     * @param off the offset in the buffer at which to start
     * @param len the number of bytes to append
     */
    public void append(byte[] buf, int off, int len) {
	resize(size + len);

	for ( int i = off; i < off + len; i++ ) {
	    bytes[size] = buf[i];
	    size++;
	}

    } //


    /**
     * Return the contents of this vector as a byte array.
     * @return the equivalent byte array
     */
    public byte[] toArray() {
	byte[] b = new byte[size];
	for ( int i = 0; i < size; i++ ) {
	    b[i] = bytes[i];
	}
	return b;
    } //


    /**
     * The resize function for the vector. Takes as an argument 
     * the minimum capacity needed. If the vector needs to be resized,
     * it first checks to see if doubling the size will be sufficient. If
     * not, it resizes to the minimum it needs.
     * @param capacity the minimum capacity needed for the vector.
     */
    private void resize(int capacity) {
	int c = bytes.length;

	if ( capacity <= c ) {
	    return;
	} else if ( capacity <= 2*c ) {
	    c = 2*c;
	} else {
	    c = capacity;
	}

	byte[] nbytes = new byte[c];
	for ( int i = 0; i < size; i++ ) {
	    nbytes[i] = bytes[i];
	}
	bytes = nbytes;
    } //

} // of class
